package jsonparser.core.lexer;

import jsonparser.exception.JSONParseException;

import java.io.IOException;
import java.io.Reader;

/**
 * Created by pendragon on 17-5-18.
 */
public class CharReader {

    private static final int BUF_SIZE = 2048;
    private char[] buf;

    int line = 1;
    int index = -1;

    private int position = 0;
    private int size = 0;

    private final Reader reader;

    public CharReader(Reader reader){
        this.reader = reader;
        buf = new char[BUF_SIZE];
    }

    protected char next() throws IOException {
        if (position == size)
            fill("EOF");
        char c = buf[position];
        index++;
        position++;

        if (c == '\n'){
            line++;
            index = -1;
        }

        return c;
    }

    /**
     * Look forward for 1 char, without moving the pointer
     * @return one char
     * @throws IOException no char, EOF encountered
     */
    protected char peek() throws IOException {
        if (position == size)
            fill("EOF");

        return buf[position];
    }

    protected String next(int size) throws IOException{
        StringBuilder sb = new StringBuilder(size);
        for (int i = 0; i < size; i++)
            sb.append(next());

        return sb.toString();
    }

    protected boolean hasMore() throws IOException {
        if (position < size)
            return true;

        fill(null);
        return position < size;
    }

    /**
     * fill(String) makes sure that the position < buf, otherwise an Exception will be thrown
     * @param append null, do nothing; str, may produce an exception
     * @throws IOException Something goes wrong
     */
    private void fill(String append) throws IOException {
        int n = reader.read(buf);
        if (n == -1){
            if (append != null)
                throw new JSONParseException(append, index);
            return;
        }

        position = 0;
        size = n;
        index += n;
    }
}
